/*     */ package com.zimbra.cs.rmgmt;
/*     */ 
/*     */ import ch.ethz.ssh2.Connection;
/*     */ import ch.ethz.ssh2.Session;
/*     */ import ch.ethz.ssh2.StreamGobbler;
/*     */ import com.zimbra.common.account.Key.ServerBy;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.ByteUtil;
/*     */ import com.zimbra.common.util.CliUtil;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Server;
/*     */ import com.zimbra.cs.util.Zimbra;
/*     */ import java.io.File;
/*     */ import java.io.IOException;
/*     */ import java.io.InputStream;
/*     */ import java.io.OutputStream;
/*     */ import java.io.PrintStream;
/*     */ import java.util.Map;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class RemoteManager
/*     */ {
/*     */   private static final int DEFAULT_REMOTE_MANAGEMENT_PORT = 22;
/*     */   private static final String DEFAULT_REMOTE_MANAGEMENT_USER = "zimbra";
/*     */   private static final String DEFAULT_REMOTE_MANAGEMENT_COMMAND = "/opt/zimbra/libexec/zmrcd";
/*     */   private File mPrivateKey;
/*     */   private final String mUser;
/*     */   private final String mHost;
/*     */   private final int mPort;
/*     */   private final String mShimCommand;
/*     */   private final String mDescription;
/*     */   private Connection mConnection;
/*     */   
/*     */   private RemoteManager(Server remote)
/*     */     throws ServiceException
/*     */   {
/*  53 */     this.mHost = remote.getAttr("zimbraServiceHostname", null);
/*  54 */     if (this.mHost == null) { throw ServiceException.FAILURE("server " + remote.getName() + " does not have a service host name", null);
/*     */     }
/*  56 */     this.mPort = remote.getIntAttr("zimbraRemoteManagementPort", 22);
/*  57 */     if (this.mPort < 0) { throw ServiceException.FAILURE("server " + remote.getName() + " has invalid " + "zimbraRemoteManagementPort", null);
/*     */     }
/*  59 */     this.mUser = remote.getAttr("zimbraRemoteManagementUser", "zimbra");
/*  60 */     if (this.mUser == null) { throw ServiceException.FAILURE("server " + remote.getName() + " has no " + "zimbraRemoteManagementUser", null);
/*     */     }
/*  62 */     this.mShimCommand = remote.getAttr("zimbraRemoteManagementCommand", "/opt/zimbra/libexec/zmrcd");
/*  63 */     if (this.mShimCommand == null) { throw ServiceException.FAILURE("server " + remote.getName() + " has no " + "zimbraRemoteManagementCommand", null);
/*     */     }
/*  65 */     Server local = Provisioning.getInstance().getLocalServer();
/*  66 */     String localName = local.getName();
/*  67 */     String privateKey = local.getAttr("zimbraRemoteManagementPrivateKeyPath", null);
/*  68 */     if (privateKey == null) {
/*  69 */       throw ServiceException.FAILURE("server " + localName + " has no " + "zimbraRemoteManagementPrivateKeyPath", null);
/*     */     }
/*     */     
/*  72 */     File key = new File(privateKey);
/*  73 */     if (!key.exists()) {
/*  74 */       throw ServiceException.FAILURE("server " + localName + " " + "zimbraRemoteManagementPrivateKeyPath" + " (" + key + ") does not exist", null);
/*     */     }
/*  76 */     if (!key.canRead()) {
/*  77 */       throw ServiceException.FAILURE("server " + localName + " " + "zimbraRemoteManagementPrivateKeyPath" + " (" + key + ") is not readable", null);
/*     */     }
/*  79 */     this.mPrivateKey = key;
/*     */     
/*  81 */     this.mDescription = ("{RemoteManager: " + localName + "->" + this.mUser + "@" + this.mHost + ":" + this.mPort + "}");
/*     */   }
/*     */   
/*     */   public String getPrivateKeyPath() {
/*  85 */     return this.mPrivateKey.getAbsolutePath();
/*     */   }
/*     */   
/*     */   public String toString() {
/*  89 */     return this.mDescription;
/*     */   }
/*     */   
/*     */   private synchronized void executeBackground0(String command, RemoteBackgroundHandler handler) {
/*  93 */     Session s = null;
/*     */     try {
/*  95 */       s = getSession();
/*  96 */       if (ZimbraLog.rmgmt.isDebugEnabled()) ZimbraLog.rmgmt.debug("(bg) executing shim command  '" + this.mShimCommand + "' on " + this);
/*  97 */       s.execCommand(this.mShimCommand);
/*  98 */       OutputStream os = s.getStdin();
/*  99 */       String send = "HOST:" + this.mHost + " " + command;
/* 100 */       if (ZimbraLog.rmgmt.isDebugEnabled()) ZimbraLog.rmgmt.debug("(bg) sending mgmt command '" + send + "' on " + this);
/* 101 */       os.write(send.getBytes());
/* 102 */       os.close();
/* 103 */       InputStream stdout = new StreamGobbler(s.getStdout());
/* 104 */       InputStream stderr = new StreamGobbler(s.getStderr());
/* 105 */       handler.read(stdout, stderr);
/*     */     } catch (OutOfMemoryError e) {
/* 107 */       Zimbra.halt("out of memory", e);
/*     */     } catch (Throwable t) {
/* 109 */       handler.error(t);
/*     */     } finally {
/* 111 */       if (s != null) {
/* 112 */         releaseSession(s);
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   public void executeBackground(final String command, final RemoteBackgroundHandler handler) {
/* 118 */     Runnable r = new Runnable() {
/*     */       public void run() {
/* 120 */         RemoteManager.this.executeBackground0(command, handler);
/*     */       }
/*     */       
/* 123 */     };
/* 124 */     Thread t = new Thread(r);
/* 125 */     t.setName(this + "-" + command);
/* 126 */     t.setDaemon(true);
/* 127 */     t.start();
/*     */   }
/*     */   
/*     */   public synchronized RemoteResult execute(String command) throws ServiceException {
/* 131 */     Session s = null;
/*     */     try {
/* 133 */       s = getSession();
/* 134 */       if (ZimbraLog.rmgmt.isDebugEnabled()) ZimbraLog.rmgmt.debug("executing shim command  '" + this.mShimCommand + "' on " + this);
/* 135 */       s.execCommand(this.mShimCommand);
/* 136 */       OutputStream os = s.getStdin();
/* 137 */       String send = "HOST:" + this.mHost + " " + command;
/* 138 */       if (ZimbraLog.rmgmt.isDebugEnabled()) ZimbraLog.rmgmt.debug("sending mgmt command '" + send + "' on " + this);
/* 139 */       os.write(send.getBytes());
/* 140 */       os.close();
/*     */       
/* 142 */       RemoteResult result = new RemoteResult();
/*     */       
/* 144 */       InputStream stdout = new StreamGobbler(s.getStdout());
/* 145 */       InputStream stderr = new StreamGobbler(s.getStderr());
/* 146 */       result.mStdout = ByteUtil.getContent(stdout, -1);
/* 147 */       result.mStderr = ByteUtil.getContent(stderr, -1);
/*     */       try {
/* 149 */         result.mExitStatus = s.getExitStatus().intValue();
/*     */       }
/*     */       catch (NullPointerException npe) {}
/*     */       
/* 153 */       if (result.mExitStatus != 0) {
/* 154 */         throw new IOException("command failed: exit status=" + result.mExitStatus + ", stdout=" + new String(result.mStdout) + ", stderr=" + new String(result.mStderr));
/*     */       }
/*     */       
/*     */ 
/*     */ 
/* 159 */       result.mExitSignal = s.getExitSignal();
/* 160 */       return result;
/*     */     } catch (IOException ioe) {
/* 162 */       throw ServiceException.FAILURE("exception executing command: " + command + " with " + this, ioe);
/*     */     } finally {
/* 164 */       if (s != null) {
/* 165 */         releaseSession(s);
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   private void releaseSession(Session sess)
/*     */   {
/*     */     try
/*     */     {
/* 174 */       sess.close();
/*     */     } finally {
/* 176 */       this.mConnection.close();
/* 177 */       this.mConnection = null;
/*     */     }
/*     */   }
/*     */   
/*     */   private Session getSession() throws ServiceException {
/*     */     try {
/* 183 */       this.mConnection = new Connection(this.mHost, this.mPort);
/* 184 */       this.mConnection.connect();
/* 185 */       if (!this.mConnection.authenticateWithPublicKey(this.mUser, this.mPrivateKey, null)) {
/* 186 */         throw new IOException("auth failed");
/*     */       }
/* 188 */       return this.mConnection.openSession();
/*     */     } catch (IOException ioe) {
/* 190 */       if (this.mConnection != null) {
/* 191 */         this.mConnection.close();
/*     */       }
/* 193 */       throw ServiceException.FAILURE("exception during auth " + this, ioe);
/*     */     }
/*     */   }
/*     */   
/*     */   public static RemoteManager getRemoteManager(Server server) throws ServiceException {
/* 198 */     return new RemoteManager(server);
/*     */   }
/*     */   
/*     */   public static void main(String[] args) throws Exception {
/* 202 */     int iterations = Integer.parseInt(args[0]);
/* 203 */     String serverName = args[1];
/* 204 */     String command = args[2];
/*     */     
/* 206 */     CliUtil.toolSetup("DEBUG");
/* 207 */     Provisioning prov = Provisioning.getInstance();
/* 208 */     Server remote = prov.get(Key.ServerBy.name, serverName);
/*     */     Map<String, String> m;
/* 210 */     for (int i = 0; i < iterations; i++) {
/* 211 */       RemoteManager rm = getRemoteManager(remote);
/* 212 */       RemoteResult rr = rm.execute(command);
/* 213 */       m = RemoteResultParser.parseSingleMap(rr);
/* 214 */       if (m == null) {
/* 215 */         System.out.println("NO RESULT RETURNED");
/*     */       } else {
/* 217 */         for (String k : m.keySet()) {
/* 218 */           System.out.println(k + "=" + (String)m.get(k));
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/rmgmt/RemoteManager.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */